package com.iwhalecloud.bss.kite.cucc.service.pos.handler.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneAccessProdInstService;
import com.iwhalecloud.bss.kite.client.dto.inst.InstAttrDTO;
import com.iwhalecloud.bss.kite.client.dto.inst.ProdInstDTO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalServiceOfferConsts;
import com.iwhalecloud.bss.kite.cucc.common.util.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.SymbolConsts;
import com.iwhalecloud.bss.kite.common.unicode.UnicodeOperTypeKite;
import com.iwhalecloud.bss.kite.common.util.KiteDateUtils;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosAttachmentDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosAttrDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosOrderDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KiteUpstreamOrderRelationDTO;
import com.iwhalecloud.bss.kite.cucc.common.constant.CuccServiceOfferConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalDcPublicConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.CuccPosServiceUtils;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.IKitePosSceneHandler;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.KitePosHandlerContext;
import com.iwhalecloud.bss.kite.cucc.service.util.ChangeTypeUtils;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProductCache;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Product;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteProdInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.manager.inst.change.KiteInstChange;
import com.iwhalecloud.bss.kite.manager.scene.service.QuerySceneInstService;
import com.iwhalecloud.bss.kite.service.ord.pos.vo.KitePosOfferInstVO;
import com.iwhalecloud.bss.kite.service.ord.pos.vo.KitePosOfferObjInstRelVO;
import com.iwhalecloud.bss.kite.service.ord.pos.vo.KitePosProdInstVO;

import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.bss.common.util.StringUtil;
import com.ztesoft.bss.svcability.util.ListUtil;

@Service
public class KitePosOrderHandler implements IKitePosSceneHandler {

    @Autowired
    private QuerySceneInstService querySceneInstService;

    @Autowired
    private IQuerySceneAccessProdInstService querySceneProdInstService;

    private static Map<String, String> bizTypeMap = new HashMap<>();

    private static Map<String, String> bizTypeNameMap = new HashMap<>();

    //private static Map<String, String> attrCodeMap = new HashMap<>();
    static {
        /*bizTypeMap.put(KeyConsts.KITE_SCENE_INST_OPER_TYPE_1000, "1001");
        bizTypeMap.put(ServiceOfferConsts.SERVICE_OFFER_MODIFY, "1002");
        bizTypeMap.put(ServiceOfferConsts.SERVICE_OFFER_STOP, "1003");
        bizTypeMap.put(ServiceOfferConsts.SERVICE_OFFER_RECOVER, "1004");
        bizTypeMap.put(ServiceOfferConsts.SERVICE_OFFER_MOVE, "1010");
        bizTypeMap.put(ServiceOfferConsts.SERVICE_OFFER_MODIFY_SPEED_UP_PACK, "1011");
        bizTypeMap.put(ServiceOfferConsts.SERVICE_OFFER_TRANSFER, "1015");

        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_BUSINESS_CHANGE, "1008");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_TARIFF_CHANGE, "1009");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_SPEED_UP, "1020");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_DECELERATION, "1021");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_IP_ADDRESS_CHANGE, "1022");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_OTHER_BUSINESS_CHANGE, "1025");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_INTERFACE_TYPE_CHANGE, "1026");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_ACCESS_CHANGE, "1027");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_ACCESS_PROTOCOL_CHANGE, "1028");

        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_BUSINESS_CHANGE, "业务变更");*/
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_ACCOUNT_CANCEL, "用户预销户");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_USER_ACCOUNT_CANCEL, "用户销户");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_PAYMENT_RELATION_CHANGE, "付费关系变更");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_RETURN, "退货");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_PIN_CARD, "销卡");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_ADD_TO, "融合追加");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_REPLACE_CHANGE_CARD, "补换卡");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_SHUTDOWN, "强制停机");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_SIM_CARD_ACCT, "SIM卡账户间转移");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_IMEI_UNTIE, "IMEI解绑");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_STOCK_MIGRA, "存量迁移");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_EARLY_PREPAY, "提前终止预付期限");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_CHANGE_BIND_IP, "变更绑定固定IP");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_ACCT_RECOVE, "账户恢复活动");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_PLAN_CHANGE_PRIV, "通信计划切换权限");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_LOCK_ACCT_ADMIN, "锁定账户管理员");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_SMS_APPLY, "申请短信接入号");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_OTHER_CHANGE, "其他变更");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_ADD_ORDER, "追加订购");
        bizTypeMap.put(CuccServiceOfferConsts.SERVICE_OFFER_ADD_PRODUCT_CHANGE, "附属产品变更");
        bizTypeMap.put(LocalServiceOfferConsts.SERVICE_OFFER_COMMERCIAL, "转商用");
        bizTypeMap.put("2815", CuccServiceOfferConsts.SERVICE_OFFER_REPLACEMENT);   // 移机 2815-》1010
        bizTypeMap.put(LocalServiceOfferConsts.SERVICE_OFFER_COP_MEMBER_JOIN, "成员加入");   // 成员加入
        bizTypeMap.put(LocalServiceOfferConsts.SERVICE_OFFER_COP_MEMBER_QUIT, "成员退出");   // 成员退出
        bizTypeMap.put(LocalServiceOfferConsts.SERVICE_OFFER_RESALE, "订单返销");   // 成员退出



        bizTypeNameMap.put("1001", "商品订购");
        bizTypeNameMap.put("1002", "商品变更");
        bizTypeNameMap.put("1003", "用户停机");
        bizTypeNameMap.put("1004", "用户复机");
        bizTypeNameMap.put("1010", "移机");
        bizTypeNameMap.put("1011", "升降速");
        bizTypeNameMap.put("1051", "弹性升速");
        bizTypeNameMap.put("1052", "取消弹性升速");
        bizTypeNameMap.put("1012", "资源核查");
        bizTypeNameMap.put("1015", "过户");

        bizTypeNameMap.put("1009", "资费变更");
        bizTypeNameMap.put("1008", "业务变更");
        bizTypeNameMap.put("1020", "升速");
        bizTypeNameMap.put("1021", "降速");
        bizTypeNameMap.put("1022", "IP地址变更");
        bizTypeNameMap.put("1025", "其他业务属性变更");
        bizTypeNameMap.put("1026", "接口类型变更");
        bizTypeNameMap.put("1027", "接入电路类型变更");
        bizTypeNameMap.put("1028", "接入协议变更");
        bizTypeNameMap.put("1080", "资料修正");
        bizTypeNameMap.put("2034", "网站或APP服务开通/关闭");
        bizTypeNameMap.put(CuccServiceOfferConsts.SERVICE_OFFER_ADD_PRODUCT_CHANGE, "附属产品变更");
        bizTypeNameMap.put(CuccServiceOfferConsts.SERVICE_OFFER_BILLING_RELATE_FIELD_CHANGE, "计费相关字段变更");

        //attrCodeMap.put("enterprise_mgr_tel", "ORD10105");
        //attrCodeMap.put("enterprise_id", "ORD10106");
        //attrCodeMap.put("attachment", "ORD10021");
        //attrCodeMap.put("remark", "ORD10022");

    }

    @Override
    public void handle(KitePosHandlerContext context) {
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(context.getSceneInstId());
        KitePosOrderDTO order = context.getPosDto().getOrder();
        if (Objects.isNull(order)) {
            order = new KitePosOrderDTO();
        }

        // 场景对象操作类型 订购，退单，初审，重提等
        // 业务变更bizType传服务提供ID
        // 支持多场景变更
        List<String> serviceOfferIdList = querySceneInstService //获取页面勾选的操作类型
            .getExtParameterValue(context.getSceneInstId(), "BUSI_CHANGE_SERVICEOFFERID");
        String serviceOfferId = sceneInst.getServiceOfferId();
        if (KiteListUtils.isNotEmpty(serviceOfferIdList) && !StringUtil.equals(sceneInst.getServiceOfferId(), "1013")) {
            List<String> serviceOfferIdTransList = getTempBizType(serviceOfferIdList);
            StringBuffer bizTypeName = new StringBuffer("");
            serviceOfferIdTransList.forEach(i -> bizTypeName.append(bizTypeNameMap.get(i)).append(","));
            order.setBizType(KiteStringUtils.join(serviceOfferIdTransList, ","));

            if(bizTypeName.length() > 0) {
                order.setBizTypeName(bizTypeName.substring(0, bizTypeName.length() - 1));
            }
        }
        else if (KiteStringUtils.equals("1008", sceneInst.getOperType())) {
            if (KiteStringUtils.equals("2826", serviceOfferId)) {
                serviceOfferId = "1008";
            }
            else if (KiteStringUtils.equals("2549", serviceOfferId)) {
                serviceOfferId = "1015";
            }
            else if (KiteStringUtils.equals("1", serviceOfferId)) {
                serviceOfferId = "2019";
            }
            else if (KiteStringUtils.equals("2829", serviceOfferId)) {
                serviceOfferId = querySceneInstService.getCommonAttrValue(sceneInst.getSceneInstId(), "RECOVER_RATIO");
            }
            else if (KiteStringUtils.equals("2830", serviceOfferId)) {
                serviceOfferId = querySceneInstService.getCommonAttrValue(sceneInst.getSceneInstId(), "STOP_RATIO");
            }
            order.setBizType(serviceOfferId);
            order.setBizTypeName(bizTypeMap.get(serviceOfferId));
        }
        else if (LocalServiceOfferConsts.SERVICE_OFFER_FOLLOW.equals(serviceOfferId)) {
            String originalServiceOfferId = querySceneInstService.getExtParameterValue(sceneInst.getSceneInstId(), "serviceOfferId", "1001");
            order.setBizType(originalServiceOfferId);
            order.setBizTypeName(bizTypeMap.get(originalServiceOfferId));
        }
        else {
            String operType = sceneInst.getOperType();
            //有映射则取映射
            List<DcPublic> dcPublics = DcPublicCache.getByPcode("20201130001", sceneInst.getOperType());
            if (!KiteListUtils.isEmpty(dcPublics)) {
                operType = dcPublics.get(0).getPkey();
            }
            order.setBizType(operType);
            order.setBizTypeName(bizTypeNameMap.get(sceneInst.getOperType()));
        }
        order.setChangeFees(UnicodeOperTypeKite.OPERTYPE_1009.equals(order.getBizType()) ? "1" : "0");
        order.setOrderType("0");
        order.setProvinceCode(context.getCustDto().getProvinceCode());
        order.setEparchyCode(context.getCustDto().getEparchyCode());

        if (Objects.isNull(context.getCustDto().getEparchyCode())) {
            order.setEparchyCode(context.getCustDto().getRegionId());
        }

        String nodeCode = querySceneInstService.getExtParameterValue(sceneInst.getSceneInstId(), "nodeCode");
        //原单
        String orderId = this.querySceneInstService.getExtParameterValue(sceneInst.getSceneInstId(), "sourceOrderId");
        if (StringUtil.isNotEmpty(orderId) && KiteStringUtils.isEmpty(nodeCode)) {
            List<KiteUpstreamOrderRelationDTO> orderRelationDTOList = new ArrayList<>();
            KiteUpstreamOrderRelationDTO orderRelationDTO = new KiteUpstreamOrderRelationDTO();
            orderRelationDTO.setGoodsInstanceId(
                querySceneInstService.getExtParameterValue(context.getSceneInstId(), "mainOfferInstId"));
            orderRelationDTO.setUpstreamOrderId(orderId);
            orderRelationDTOList.add(orderRelationDTO);
            order.setUpstreamOrderRelation(orderRelationDTOList);
        }
        //原单
        String resourceCheckOrderId = this.querySceneInstService.getExtParameterValue(sceneInst.getSceneInstId(), "resourceCheckOrderId");
        if (StringUtil.isNotEmpty(resourceCheckOrderId) && KiteStringUtils.isEmpty(nodeCode)) {
            List<KiteUpstreamOrderRelationDTO> orderRelationDTOList = new ArrayList<>();
            KiteUpstreamOrderRelationDTO orderRelationDTO = new KiteUpstreamOrderRelationDTO();
            orderRelationDTO.setGoodsInstanceId(
                querySceneInstService.getExtParameterValue(context.getSceneInstId(), "mainOfferInstId"));
            orderRelationDTO.setUpstreamOrderId(resourceCheckOrderId);
            orderRelationDTOList.add(orderRelationDTO);
            order.setUpstreamOrderRelation(orderRelationDTOList);
        }

        // 核查转定和资源核查才组装FlowControl节点
        String flowControl = this.getFlowControl(sceneInst.getServiceOfferId());
        if (KiteStringUtils.isNotEmpty(flowControl)) {
            order.setFlowControl(flowControl);
        }

        Date createDate = querySceneInstService.getSceneInst(context.getSceneInstId()).getCreateDate();
        String createDateStr = KiteDateUtils.formatDate(createDate, KiteDateUtils.DATE_TIME_FORMAT_14);

        // 业务属性，如收货信息、集团用户信息
        List<KiteAttr> busiAttrs = Lists.newArrayList();
        List<DcPublic> publics = DcPublicCache.get(LocalDcPublicConsts.BUSI_ATTR_MODULE);
    	if(CuccPosServiceUtils.isRouteUser(context.getSceneInstId(),context.getCustId())) {
    		publics = publics.stream().filter(pp -> !KiteStringUtils.equals(pp.getPcode(),LocalKeyConsts.CUSTMANAGERINFO_MODULEID) && !KiteStringUtils.equals(pp.getPcode(),LocalKeyConsts.GROUPUSERINFO_MODULEID)).collect(Collectors.toList());
            busiAttrs.addAll(dealUserField(context));
    	}
        publics.forEach(ppp -> {
            List<KiteAttr> kiteAttrs = querySceneInstService.listCommonAttrsByModuleId(context.getSceneInstId(), ppp.getPcode());
            if ("210".equals(ppp.getPcode()) && KiteListUtils.isNotEmpty(kiteAttrs)) {
                String checked = querySceneInstService.getCommonAttrValue(context.getSceneInstId(), "IpAddressRecordInfo");
                if (!LocalKeyConsts.IFTRUE_T.equals(checked)) {
                    return;
                }
                kiteAttrs.removeIf(kiteAttr -> "IpAddressRecordInfo".equals(kiteAttr.getFieldName()));
            }
            busiAttrs.addAll(kiteAttrs);
        });

        List<KitePosAttrDTO> attrs = order.getAttrs();
        if (KiteListUtils.isEmpty(attrs)) {
            attrs = new ArrayList<>();
        }
        for (KiteAttr kiteAttr : busiAttrs) {
            //属性值为空不传到下游系统
            if (KiteStringUtils.isEmpty(kiteAttr.getValue())||KiteStringUtils.equals(kiteAttr.getShowType(),"E")) {
                continue;
            }
            if (!attrs.stream().anyMatch((attr) -> KiteStringUtils.isEqual(attr.getCode(), kiteAttr.getFieldName()))) {
                KitePosAttrDTO attr = new KitePosAttrDTO();
                attr.setCode(kiteAttr.getFieldName());
                attr.setType("STRING");
                attr.setStartDate(createDateStr);
                attr.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
                attr.setValue(kiteAttr.getValue() == null ? "" : kiteAttr.getValue());
//              全程要求完成时间精确到分,补00
                if(LocalKeyConsts.REQUIRED_FINISH_TIME.contains(kiteAttr.getFieldName()) && kiteAttr.getValue() != null){
                    attr.setValue(kiteAttr.getValue().length()==16?(kiteAttr.getValue()+ DateUtils.SECOND):kiteAttr.getValue());
                }
                attrs.add(attr);
            }
            else {
                //如果有匹配的属性并且值不相等,那么取场景中的数据更新转单
                KitePosAttrDTO posAttr = attrs.stream().filter(attr ->
                    KiteStringUtils.isEqual(attr.getCode(), kiteAttr.getFieldName())
                    && !KiteStringUtils.isEqual(attr.getValue(), kiteAttr.getValue())).findFirst().orElse(null);
                if (Objects.nonNull(posAttr)) {
                    posAttr.setValue(kiteAttr.getValue() == null ? "" : kiteAttr.getValue());
                }
            }
        }

        // 云账号注册增加起租时间
        String cateId = CuccPosServiceUtils.getCateId(context.getSceneInstId(), context.getCustId());
        if (KiteStringUtils.equalsAny(cateId, "2000998", "2100982", "2100983")) {
            dealPosAttr(attrs, LocalKeyConsts.START_RENT_DATE, KiteDateUtils.formatDate(createDate, KiteDateUtils.DATE_FORMAT), createDateStr);
        }
        String dcPublic = DcPublicCache.getPCode("20210506001", cateId);
        if (KiteStringUtils.isNotEmpty(dcPublic)) {
            dealPosAttr(attrs, "ORD10263", (String) ContextUtil.getLoginInfo().getStaffInfo().getStaffCode(), createDateStr);
        }
        //获取当前工号ID
        dealPosAttr(attrs, "ORD10114", (String) ContextUtil.getLoginInfo().getUserInfo().getExtParams().get("accountId"), createDateStr);
        //获取当前工号编码
        dealPosAttr(attrs, "ORD10115", (String) ContextUtil.getLoginInfo().getUserInfo().getExtParams().get("account"), createDateStr);
        //获取当前工号姓名
        //dealPosAttr(attrs, "ORD10116", KiteStringUtils.valueOf(ContextUtil.getLoginInfo().getStaffInfo().getStaffName()), createDateStr);

        // 用户归属省份地市区县
        String userLocation = querySceneInstService.getCommonAttrValue(context.getSceneInstId(), "user_location");
        String provinceCode = userLocation.split(",").length > 1 ? userLocation.split(",")[0] : "";
        String eparchyCode = userLocation.split(",").length > 1 ? userLocation.split(",")[1] : "";
        String cityCode = userLocation.split(",").length > 2 ? userLocation.split(",")[2] : "";
        dealPosAttr(attrs, "provinceCode", provinceCode, createDateStr);
        dealPosAttr(attrs, "eparchyCode", eparchyCode, createDateStr);
        dealPosAttr(attrs, "cityCode", cityCode, createDateStr);
        dealGoodsAttr(context,attrs, createDateStr);

        this.addResaleAttr(context.getSceneInstId(), attrs, createDateStr);

        // 售前信息
        List<KiteAttr> preSalesInfoAttrs = busiAttrs.stream()
            .filter((attr) -> LocalKeyConsts.PROD_ATTR_SHOW_TYPE_S.equals(attr.getShowType())).collect(Collectors.toList());
        if (!ListUtil.isEmpty(preSalesInfoAttrs)) {
            for (KiteAttr kiteAttr : preSalesInfoAttrs) {
                if (!attrs.stream().anyMatch((attr) -> attr.getCode().equals(kiteAttr.getFieldName()))) {
                    KitePosAttrDTO attr = new KitePosAttrDTO();
                    attr.setCode(kiteAttr.getFieldName());
                    attr.setType("STRING");
                    attr.setStartDate(createDateStr);
                    attr.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
                    attr.setValue(kiteAttr.getValue() == null ? "" : kiteAttr.getValue());

                    attrs.add(attr);
                }
                else {
                    for (KitePosAttrDTO attr: attrs) {
                        if (attr.getCode().equals(kiteAttr.getFieldName()) && !Objects.equals(attr.getValue(), kiteAttr.getValue())) {
                            attr.setStartDate(createDateStr);
                            attr.setValue(kiteAttr.getValue() == null ? "" : kiteAttr.getValue());
                            break;
                        }
                    }
                }
            }
        }

        //其他公共属性
        List<KiteAttr> commAttrs = querySceneInstService
            .listCommonAttrs(context.getSceneInstId(), KeyConsts.COMMON_OBJECT_TYPE);
        List<KiteAttr> commAttr = commAttrs.stream()
            .filter((attr) -> !LocalKeyConsts.COMMON_ATTR_KEY_ATTACHMENT.equals(attr.getFieldName()))
            .collect(Collectors.toList());
        if (!KiteListUtils.isEmpty(commAttr)) {
            for (KiteAttr kiteAttr : commAttr) {
                if(KiteStringUtils.equals(kiteAttr.getShowType(),"E")){
                    continue;
                }
                if ("ORD10022".equals(kiteAttr.getFieldName())) {
                    order.setRemark(kiteAttr.getValue() == null ? "" : kiteAttr.getValue());
                    // 转单报文订单属性节点 新增附件及备注模块的备注信息
                    dealPosAttr(attrs, kiteAttr.getFieldName(), Optional.ofNullable(kiteAttr.getValue()).orElse(""), createDateStr);
                }
                else {
                    //              全程要求完成时间精确到分,补00
                    if(LocalKeyConsts.REQUIRED_FINISH_TIME.contains(kiteAttr.getFieldName()) && kiteAttr.getValue() != null){
                        kiteAttr.setValue(kiteAttr.getValue().length()==16?(kiteAttr.getValue()+ DateUtils.SECOND):kiteAttr.getValue());
                    }
                    dealPosAttr(attrs, kiteAttr.getFieldName(), Optional.ofNullable(kiteAttr.getValue()).orElse(""), createDateStr);
                }
            }
        }
        // 起租属性封装到order节点的attrs中
        List<KiteAttr> startRentTimeAttrs = querySceneInstService.listCommonAttrsByModuleId(context.getSceneInstId(), LocalKeyConsts.START_RENT_INFO_MODULE);
        if (KiteListUtils.isNotEmpty(startRentTimeAttrs)) {
            for (KiteAttr startRentTimeAttr : startRentTimeAttrs) {
                if (LocalKeyConsts.START_RENT_DATE.equals(startRentTimeAttr.getFieldName())) {
                    dealPosAttr(attrs, startRentTimeAttr.getFieldName(), Optional.ofNullable(startRentTimeAttr.getValue()).orElse(""), createDateStr);
                }
            };
        }
        //物联网实名制封装到order attrs中
        List<KiteAttr>  registrAttrs = querySceneInstService.listCommonAttrsByModuleId(context.getSceneInstId(), LocalKeyConsts.MODULE_ID_REGISTRATION).stream().filter(
            kiteAttr->"ORD10293".equals(kiteAttr.getFieldName())&&!KiteStringUtils.isEmpty(kiteAttr.getValue())&& !KiteStringUtils.equals(kiteAttr.getValue(),"null") ).collect(Collectors.toList());
        if (!KiteListUtils.isEmpty(registrAttrs)) {
            for (KiteAttr registrAttr : registrAttrs) {
                dealPosAttr(attrs, registrAttr.getFieldName(), Optional.ofNullable(registrAttr.getValue()).orElse(""), createDateStr);
            }
        }

        //五大双线产品,停开机菜单合并需求,属性组装
        List<KiteAttr> stopOrRecoverAttrs = new ArrayList<>();
        if ("2829".equals(sceneInst.getServiceOfferId())) {
            stopOrRecoverAttrs = querySceneInstService.listCommonAttrsByModuleId(context.getSceneInstId(), "130").stream()
                .filter(kiteAttr -> !"RECOVER_RATIO".equals(kiteAttr.getFieldName())).collect(Collectors.toList());
        }
        else if ("2830".equals(sceneInst.getServiceOfferId())) {
            stopOrRecoverAttrs = querySceneInstService.listCommonAttrsByModuleId(context.getSceneInstId(), "129").stream()
                .filter(kiteAttr -> !"STOP_RATIO".equals(kiteAttr.getFieldName())).collect(Collectors.toList());
        }
        for (KiteAttr stopOrRecoverAttr : stopOrRecoverAttrs) {
            dealPosAttr(attrs, stopOrRecoverAttr.getFieldName(), Optional.ofNullable(stopOrRecoverAttr.getValue()).orElse(""), createDateStr);
        }

        //个人客户需要将数据传给后端 上海极简个人需求，这里不需要 add by sqy 20210208
//        if(KiteStringUtils.equals(context.getCustDto().getCustType(), "0")) {
//            KitePosAttrDTO attr = new KitePosAttrDTO();
//            attr.setCode("CUST_TYPE");
//            attr.setType("STRING");
//            attr.setStartDate(createDateStr);
//            attr.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
//            attr.setValue(context.getCustDto().getCustType());
//            attrs.add(attr);
//        }
        // 是否配置变更
        String isMod = getIsMod(context, order.getBizType());
        dealPosAttrNoAdd(attrs, "ORD10199", isMod);

        if("1080".equals(order.getBizType())) {
            // 操作类型=资料修正，则订单性质=资料修正单
            dealPosAttr(attrs, "ORD10001", "8", createDateStr);
        }

        if(KiteListUtils.isNotEmpty(attrs)){
            attrs = attrs.stream().filter( dto -> !KiteStringUtils.isEmpty(dto.getValue()) && !KiteStringUtils.equals(dto.getValue(),"null") ).collect(Collectors.toList());
            if("2000991".equals(cateId)||"2100949".equals(cateId)||"2000993".equals(cateId)){
                attrs.removeIf(dto -> isFilterFieldJf(dto.getCode()));
            }
        }
        order.setAttrs(attrs);
        //封装附件
        List<KiteAttr> attachements = commAttrs.stream()
            .filter((attr) -> LocalKeyConsts.COMMON_ATTR_KEY_ATTACHMENT.equals(attr.getFieldName()))
            .collect(Collectors.toList());
        if (!KiteListUtils.isEmpty(attachements) && !KiteStringUtils.equals(attachements.get(0).getValue(),"[]")) {
            KiteAttr kiteAttr = attachements.get(0);
            List<KitePosAttachmentDTO> attachments = new ArrayList<>();
            String jsonStr = kiteAttr.getValue();
            if (!KiteStringUtils.isEmpty(jsonStr)) {
                JSONArray arrs = JSONArray.parseArray(jsonStr);
                for (int i = 0; i < arrs.size(); i++) {
                    JSONObject obj = arrs.getJSONObject(i);
                    KitePosAttachmentDTO attaDto = new KitePosAttachmentDTO();
                    attaDto.setUrl(obj.getString("attachmentUrl"));
                    attaDto.setCatagory(obj.getString("fileType").replace("ATTACHMENTS_TYPE_", ""));
                    String name = obj.getString("fileName");
                    if (KiteStringUtils.isNotEmpty(obj.getString("type"))) {
                        name = KiteStringUtils.join(obj.getString("fileName"), SymbolConsts.PERIOD, obj.getString("type"));
                    }
                    attaDto.setName(name);
                    attaDto.setUploadTime(obj.getString("createDate"));
                    attaDto.setChangeType(ChangeTypeUtils.getChangeType(obj.getString("actionType")));
                    attachments.add(attaDto);
                }
            }
            order.setAttachments(attachments);
        } else if(!KiteListUtils.isEmpty(attachements) && KiteStringUtils.equals(attachements.get(0).getValue(),"[]")){
            List<KitePosAttachmentDTO> attachments = new ArrayList<>();
            order.setAttachments(attachments);
        }

        // 落地方补录提交，新增参数，用于关闭落地方补录代办
        String renderOrderType = querySceneInstService.getExtParameterValue(context.getSceneInstId(), "renderOrderType");
        if(KiteStringUtils.isEqual(renderOrderType, "orderFallPlace")) {
            String worksheetId = querySceneInstService.getExtParameterValue(context.getSceneInstId(), "fallPlaceFlowId");
            KitePosAttrDTO attr = new KitePosAttrDTO();
            attr.setCode("worksheetID");
            attr.setType("STRING");
            attr.setStartDate(createDateStr);
            attr.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
            attr.setValue(worksheetId);
            attrs.add(attr);

            // 落地方产品补录，多传3个参数
            String initiatorOrderId = querySceneInstService.getExtParameterValue(context.getSceneInstId(), "fallPlaceOrderId");
            if(KiteStringUtils.isNotEmpty(initiatorOrderId)) {
                order.setSymbol("00");

                order.setInitiatorOrderId(initiatorOrderId);
                List<ProdInstDTO> prodInstLists = querySceneProdInstService.listEffProdInsts(context.getSceneInstId(), context.getCustId()).getResultObject();
                if(KiteListUtils.isEmpty(prodInstLists)) {
                    return;
                }
                List<InstAttrDTO> instAttrDTOS = prodInstLists.get(0).getInstAttrDTOS();
                String initiatorSerialNumber = instAttrDTOS.stream().filter(instAttrDTO -> KiteStringUtils.isEqual("200002059", instAttrDTO.getFieldName()))
                    .findAny().map(InstAttrDTO::getValue).orElse(null);
                order.setInitiatorSerialNumber(initiatorSerialNumber);
            }
        }

        // app甩单补录，将goods节点下的code、name、saleGoodsCode复制一份到order节点下（goodsCode、goodsNames、saleGoods）
        // 获取较麻烦，在goods节点赋值时，再给order节点同步一份，见 KitePosGoodsHandler

        // 资源核查甩单补录，将订单性质改为正常单（0正常单：；4：业务意向单），来单原为业务意向单
        if(KiteStringUtils.isEqual(renderOrderType, "orderRejection") && KiteStringUtils.isEqual(serviceOfferId, "1012")) {
            dealPosAttr(attrs, "ORD10001", "0", createDateStr);
        }

        context.getPosDto().setOrder(order);
    }

    private String getIsMod(KitePosHandlerContext context, String bizType) {
        String value = "1";
        List<String> cateIds = CuccPosServiceUtils.listCateIds(context.getSceneInstId(), context.getCustId());

        String customizedCateIdStr = DcPublicCache.getCodea("2021031501", "customized");
        if (KiteStringUtils.isEmpty(customizedCateIdStr)) {
            return value;
        }
        String[] customizedCateIds = customizedCateIdStr.split(SymbolConsts.COMMA);
        if (customizedCateIds.length == 0) {
            return value;
        }
        // 订购时，如果有定制链接类产品 2000957，走双审 0 ，其他情况走单审 1 ；
        // 变更时，如果有定制连接类产品且变更了配置信息，走双审，其他情况走单审
        if (cateIds.stream().anyMatch(s -> KiteStringUtils.equalsAny(s, customizedCateIds))) {
            // 订购
            if (KiteStringUtils.isEqual(bizType, "1001") || KiteStringUtils.isEqual(bizType, "2019")) {
                value = "0";
            }
            else if (KiteStringUtils.isEqual(bizType, "1008")) {
                List<KiteInstChange> instProdChangeList = querySceneInstService
                    .listInstChanges(context.getSceneInstId(), InstType.PROD_INST);
                if (KiteListUtils.isEmpty(instProdChangeList) || isProdAttrUnmodified(context, instProdChangeList)) {
                    // 没有产品属性变更，走单审
                    value = "1";
                }
                // 存在功能产品变动，走双审
                List<KiteInst> kiteInstList = querySceneInstService.listInsts(context.getSceneInstId(), Lists.newArrayList(InstType.PROD_INST_FUNC));
                if (kiteInstList.stream().anyMatch(kiteInst -> ActionType.A.equals(kiteInst.getActionType())
                    || ActionType.D.equals(kiteInst.getActionType()) || ActionType.M.equals(kiteInst.getActionType()))) {
                    value = "0";
                }
                List<KiteInstChange> instProdFuncChangeList = querySceneInstService
                    .listInstChanges(context.getSceneInstId(), InstType.PROD_INST_FUNC);
                if (KiteListUtils.isNotEmpty(instProdFuncChangeList)) {
                    value = "0";
                }
            }
        }

        return value;
    }

    private boolean isProdAttrUnmodified(KitePosHandlerContext context, List<KiteInstChange> instProdChangeList) {
        //默认没有产品属性修改
        boolean flag = true;
        for (KiteInstChange instProdChange : instProdChangeList) {
            if (KiteStringUtils.isEmpty(instProdChange.getFieldName()) && !KiteStringUtils
                .isEqual(instProdChange.getActionType().name(), ActionType.K.name())) {
                KiteInst inst = querySceneInstService
                    .getKiteInst(context.getCustId(), instProdChange.getInstType(), instProdChange.getInstId());
                // 涉及场景还原的(比如变更、重提) 资费计划的产品实例是会重新生成的,这里过滤掉
                if (InstType.PROD_INST.name().equals(inst.getInstType().name()) && KiteStringUtils
                    .isEqual("500000000", ProductCache.get(inst.getSpecId()).getProdNbr())) {
                    continue;
                }
                flag = false;
                break;
            }
            KiteAttr kiteAttr = querySceneInstService
                .getProdInstAttr(context.getCustId(), instProdChange.getInstId(), instProdChange.getFieldName());
            // 业务信息不参入校验
            if (Objects.isNull(kiteAttr) || KiteStringUtils.isEqual(kiteAttr.getGroupId(), "300000149")) {
                continue;
            }
            //联动隐藏的属性不传到下游系统,也不做校验是否有变动
            if (KiteStringUtils.equals(kiteAttr.getShowType(), KeyConsts.PROD_ATTR_SHOW_TYPE_E)) {
                continue;
            }
            if (KiteStringUtils.equals(instProdChange.getActionType().name(), ActionType.M.name())) {
                if (!KiteStringUtils.isEqual(kiteAttr.getOriginValue(), kiteAttr.getValue())) {
                    //有产品属性修改，设置为false
                    flag = false;
                    break;
                }
            }
            else {
                flag = false;
                break;
            }
        }
        return flag;
    }

    private void dealPosAttr(List<KitePosAttrDTO> attrs, String code, String value, String startDate) {
        KitePosAttrDTO posAttr = attrs.stream().filter(attr -> KiteStringUtils.equals(code, attr.getCode())).findFirst().orElse(null);
        if (Objects.isNull(posAttr)) {
            KitePosAttrDTO staffIdAttr = new KitePosAttrDTO();
            staffIdAttr.setCode(code);
            staffIdAttr.setType("STRING");
            staffIdAttr.setStartDate(startDate);
            staffIdAttr.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
            staffIdAttr.setValue(value);
            attrs.add(staffIdAttr);
        }
        else {
            posAttr.setValue(value);
        }
    }

    private void dealPosAttrNoAdd(List<KitePosAttrDTO> attrs, String code, String value) {
        KitePosAttrDTO posAttr = attrs.stream().filter(attr -> KiteStringUtils.equals(code, attr.getCode())).findFirst().orElse(null);
        if (Objects.nonNull(posAttr)) {
            posAttr.setValue(value);
        }
    }

    private String getProdId(KitePosHandlerContext context) {
    	String prodId = "";
    	Map<String, KitePosOfferInstVO> mainOfferInstMap = context.getPosSceneBO().getMainOfferInstMap();
        Iterator<KitePosOfferInstVO> iterator = mainOfferInstMap.values().iterator();
        while (iterator.hasNext()) {
            KitePosOfferInstVO offerInstVO = iterator.next();
            //套餐实例
            KiteOfferInst offerInst = offerInstVO.getOfferInst(); //套餐实例
            List<KitePosOfferObjInstRelVO> objInstRels = offerInstVO.getOfferObjInstRels();
            Map<String, KitePosProdInstVO> prodInstMap = context.getPosSceneBO().getProdInstMap();
            for (KitePosOfferObjInstRelVO instRel : objInstRels) {
            	String instId = instRel.getInstId();
            	KitePosProdInstVO prodInstVO = prodInstMap.get(instId);
            	if (Objects.nonNull(prodInstVO) && Objects.nonNull(prodInstVO.getProdInst())) {
            		KiteProdInst prodInst = prodInstVO.getProdInst();

            		//通过BillProdType区分是基础产品还是资费类产品，这里取基础产品
            		Product prodSpec = ProductCache.get(prodInst.getProdId());
            		String prodUseType = prodSpec.getProdUseType();
            		// 不封装useType=2000的产品，如资费计划产品是配成了2000
            		if (KiteStringUtils.equals(prodUseType, LocalKeyConsts.PROD_USE_TYPE_2000)) {
            			continue;
            		}
            		prodId = prodInst.getProdId();
            	}
            }
        }
        return prodId;
    }

    private void dealGoodsAttr(KitePosHandlerContext context, List<KitePosAttrDTO> attrs, String createDateStr) {
    	if(CuccPosServiceUtils.isRouteUser(context.getSceneInstId(),context.getCustId())) {
            Product prod = ProductCache.get(getProdId(context));
            if (Objects.nonNull(prod)) {
                // 电信类型
                KitePosAttrDTO teleTypeAttr = attrs.stream()
                    .filter(attr -> KiteStringUtils.equals("ORD10247", attr.getCode())).findFirst().orElse(null);
                if (Objects.isNull(teleTypeAttr)) {
                    teleTypeAttr = new KitePosAttrDTO();
                    teleTypeAttr.setCode("ORD10247");
                    teleTypeAttr.setType("STRING");
                    teleTypeAttr.setStartDate(createDateStr);
                    teleTypeAttr.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
                    teleTypeAttr.setValue(Optional.ofNullable(prod.getServiceTypeCode()).orElse(""));
                    attrs.add(teleTypeAttr);
                }
                else {
                    teleTypeAttr.setType("STRING");
                    teleTypeAttr.setStartDate(createDateStr);
                    teleTypeAttr.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
                    teleTypeAttr.setValue(Optional.ofNullable(prod.getServiceTypeCode()).orElse(""));
                }

                // 品牌
                KitePosAttrDTO brandAttr = attrs.stream()
                    .filter(attr -> KiteStringUtils.equals("ORD10248", attr.getCode())).findFirst().orElse(null);
                if (Objects.isNull(brandAttr)) {
                    brandAttr = new KitePosAttrDTO();
                    brandAttr.setCode("ORD10248");
                    brandAttr.setType("STRING");
                    brandAttr.setStartDate(createDateStr);
                    brandAttr.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
                    brandAttr.setValue(Optional.ofNullable(prod.getBrandCode()).orElse(""));
                    attrs.add(brandAttr);
                }
                else {
                    brandAttr.setType("STRING");
                    brandAttr.setStartDate(createDateStr);
                    brandAttr.setEndDate(LocalKeyConsts.ATTR_SEND_DATE);
                    brandAttr.setValue(Optional.ofNullable(prod.getBrandCode()).orElse(""));
                }
            }
        }
    }
    private List<KiteAttr> dealUserField(KitePosHandlerContext context) {
    	List<KiteAttr> busiAttrs = Lists.newArrayList();
        List<KiteAttr> groupUserInfos = querySceneInstService.listCommonAttrsByModuleId(context.getSceneInstId(), LocalKeyConsts.GROUPUSERINFO_MODULEID);
        // 0511 改造计费周期、付费类型、计费类型、缴费周期、账务周期放在user节点传给订单中心
        if (KiteListUtils.isNotEmpty(groupUserInfos)) {
            groupUserInfos.removeIf(groupUserInfo -> KiteStringUtils.equalsAny(groupUserInfo.getFieldName(),
                "ORD10235", "ORD10236", "ORD10240", "ORD10233", "ORD10234"));
        }
        busiAttrs.addAll(groupUserInfos);
        busiAttrs = busiAttrs.stream().filter(attr -> isFilterField(attr.getFieldName())).collect(Collectors.toList());
        return busiAttrs;
    }
    private boolean isFilterField(String filedName) {
    	boolean result = false;
    	DcPublic dp = DcPublicCache.get("20210208002",filedName);
    	if(Objects.nonNull(dp)) {
    		result = true;
    	}
    	return result;
    }

    private String getFlowControl(String serviceOfferId) {
        return DcPublicCache.getPCode(LocalDcPublicConsts.DC_200518999, serviceOfferId);
    }

    private List<String> getTempBizType(List<String> list){
        List<String> result = new ArrayList<String>();
        for(String bizType : list) {
            result.add(bizTypeMap.get(bizType) != null ?
                    bizTypeMap.get(bizType) :
                        bizType);
        }
        return result;
    }
    private boolean isFilterFieldJf(String filedName) {
        boolean result = false;
        DcPublic dp = DcPublicCache.get("20210629001",filedName);
        if(Objects.nonNull(dp)) {
            result = true;
        }
        return result;
    }

    /**
     * 返销需要在order.attrs下拼接sourceOrderId属性
     * @param sceneInstId
     * @param attrs
     * @param createDate
     */
    private void addResaleAttr(String sceneInstId, List<KitePosAttrDTO> attrs, String createDate) {
        String sceneResale = querySceneInstService.getExtParameterValue(sceneInstId, "SCENE_RESALE");
        if (KiteStringUtils.equals(sceneResale, "resale")) {
            String sourceOrderId = querySceneInstService.getExtParameterValue(sceneInstId, "RESALE_ORDER_ID");
            dealPosAttr(attrs, "sourceOrderId", sourceOrderId, createDate);
        }
    }
}
